home *** CD-ROM | disk | FTP | other *** search
Wrap
/************************************************************************ * * * TextExport.c * * * * Translator for writing a text file with XTND 1.3. This translator * * does not support headers, footers, pictures, or footnotes, since * * it writes only simple, unstructured ASCII files. * * * * Copyright © 1989,90 Claris Corporation * * All Rights Reserved * * * * Author: Lyndley Crumly * * Date: 12 February, 1990 * * * ************************************************************************/ /***** Note: This project MUST be compiled and merged after TextImport.π *****/ /***** is compiled, since that project replaces the resources in the *****/ /***** Text translator when it is built, including the resource *****/ /***** created by this project. *****/ #include <StandardFile.h> #include <Memory.h> #include <Printing.h> #include ":::XTND Headers:XTNDCIncludes:XTNDTextTranslator.h" /*------------------------- Useful Constants ---------------------------*/ #define kBufferSize 512 #define kSpaceChar 0x20 /*-------------------------Global Variables-----------------------------*/ /* The translator globals structure is used to store our import */ /* translator’s translator’s private global variables. A relocatable */ /* block is created in the application heap when the translator */ /* receives the EXPORT_INIT directive and a handle to the globals */ /* are stored in the GlobalHandle field of the Export Parameter Block */ /* passed into the translator from the application. The globals block */ /* is freed when the translator receives the EXPORT_CLOSE_ALL directive.*/ /* We are going to lock down the global handle when it is created and */ /* leave it that way so as to avoid any problems with dereferenced */ /* pointers. You may choose to unlock the global handle when feasible. */ typedef struct TransGlobals { unsigned char tempBuffer[kBufferSize]; /* Memory buffer where data to be written to the disk file is stored */ long filePos; /* This stores our current file position. Since the file is written linearly from start to finish, this is always the next position in the file that we will write to. */ long tempBufferPos; /* This stores the current amount of text in the memory buffer which has not yet been written to the output file */ } TMyGlobals, *TMyGlobalPtr, **TMyGlobalHandle; /*-------------------------Function prototypes--------------------------*/ void main(ExportParmBlkPtr exportPBPtr); static void CloseMain(ExportParmBlkPtr exportPBPtr, TMyGlobalPtr myGlobalPtr); static void WriteText(ExportParmBlkPtr exportPBPtr, TMyGlobalPtr myGlobalPtr); static void PutChar(char ch, ExportParmBlkPtr exportPBPtr, TMyGlobalPtr myGlobalPtr); static void WriteTempBuffer(long position, long count, unsigned char *bufptr, ExportParmBlkPtr exportPBPtr, TMyGlobalPtr myGlobalPtr); /*----------------------------------------------------------------------*/ /* main This is the main routine and the only entry point for the */ /* the translator. This routine actually performs all of the */ /* work of the translator. It dispatches the call to the */ /* appropriate routine depending on the directive and */ /* translator state. */ /*----------------------------------------------------------------------*/ void main(ExportParmBlkPtr exportPBPtr) { switch(exportPBPtr->directive) { case exportInitAll: /* Initialize the translator. This must be */ /* the first call to the translator. */ if (!(exportPBPtr->globalHandle = NewHandle(sizeof(TMyGlobals)))) *exportPBPtr->result = MemError(); else { MoveHHi(exportPBPtr->globalHandle); HLock(exportPBPtr->globalHandle); ((TMyGlobalPtr)*exportPBPtr->globalHandle)->filePos = 0; ((TMyGlobalPtr)*exportPBPtr->globalHandle)->tempBufferPos = 0; } break; case exportOpenMain: /* Initialize the main story. */ /* Nothing needs to be done here. */ exportPBPtr->directive = exportAcknowledge; break; case exportWriteText: /* Write the next text run to the file. */ /* This translator only exports the */ /* main body. */ WriteText(exportPBPtr, (TMyGlobalPtr)*exportPBPtr->globalHandle); break; case exportCloseMain: /* Close the main story when finished */ /* with it. */ CloseMain(exportPBPtr, (TMyGlobalPtr)*exportPBPtr->globalHandle); break; case exportCloseAll: /* Shutting down. */ CloseMain(exportPBPtr, (TMyGlobalPtr)*exportPBPtr->globalHandle); if (exportPBPtr->globalHandle) { DisposHandle(exportPBPtr->globalHandle); (exportPBPtr->globalHandle) = 0L; } break; case exportWriteResources: /* We don't write any resources */ exportPBPtr->directive = exportAcknowledge; break; default: /* We don't show the directives that we */ break; /* don't use. They are all taken care */ /* of by default, which does nothing */ /* at all. */ } } /*----------------------------------------------------------------------*/ /* CloseMain This routine closes the main story if it has not yet */ /* been closed. This mainly consists of writing any remaining */ /* text from the memory buffer to the output file. */ /*----------------------------------------------------------------------*/ static void CloseMain(register ExportParmBlkPtr exportPBPtr, register TMyGlobalPtr myGlobalPtr) { /* If there is text remaining in the buffer write it to the file. */ if (myGlobalPtr->tempBufferPos != 0) { /* Check for text in the buffer */ WriteTempBuffer(myGlobalPtr->filePos, myGlobalPtr->tempBufferPos, myGlobalPtr->tempBuffer, exportPBPtr, myGlobalPtr); myGlobalPtr->tempBufferPos = 0; /* Indicate that the buffer is empty */ } } /*----------------------------------------------------------------------*/ /* WriteText This routine writes each text run received from the */ /* application. */ /*----------------------------------------------------------------------*/ static void WriteText(register ExportParmBlkPtr exportPBPtr, register TMyGlobalPtr myGlobalPtr) { char ch; /* The next character from the text buffer */ char *writeTextPtr; /* Pointer to position in the text buffer */ long i; /* Loop index */ long charsInRun = *exportPBPtr->textLength; /* Length of the run */ /* Since the output text buffer is a handle, unlike the input text */ /* text buffer, we first lock the handle, and then set up a pointer */ /* to our current position in the buffer. */ HLock(exportPBPtr->textBuffer); /* Lock the buffer */ writeTextPtr = *exportPBPtr->textBuffer; /* Set up pointer to text */ /* Process each character in the text buffer and write it to the */ /* output file. Some of the character conversion is arbitrary and */ /* could equally be done some other way. */ for (i = 0;i < charsInRun; i++) { ch = *writeTextPtr++; /* Get the next character */ switch (ch) { case softHyphen: /* Discretionary hyphen character */ break; /* This character is not written */ case mergeBreak: /* Merge break */ case newColumn: /* Column break */ case newPage: /* Page break */ PutChar(returnChar, exportPBPtr, myGlobalPtr); break; /* These are all changed to return characters */ case pageNumber: /* Page number */ case footnoteChar: /* Footnote reference within a footnote */ case footnoteMark: /* Footnote reference within main body */ case floatingPict: /* Floating picture */ case shortDateChar: /* Short date */ case abbrDateChar: /* Abbreviated date */ case longDateChar: /* Long date */ case dayAbbrDateChar: /* Abbreviated date with day */ case dayLongDateChar: /* Long date with day */ case timeChar: /* Time */ case kSpaceChar: /* Space character */ PutChar(kSpaceChar, exportPBPtr, myGlobalPtr); break; /* These are all changed to space characters */ default: /* All other characters */ PutChar(ch, exportPBPtr, myGlobalPtr); break; /* These are written without any conversion */ } } HUnlock(exportPBPtr->textBuffer); /* Unlock the buffer */ } /*----------------------------------------------------------------------*/ /* PutChar This routine writes the given character to the memory */ /* buffer and automatically writes the memory buffer to the */ /* output file when it is full. */ /*----------------------------------------------------------------------*/ static void PutChar(char ch, register ExportParmBlkPtr exportPBPtr, register TMyGlobalPtr myGlobalPtr) { if (*exportPBPtr->result) return; /* Cancel if a previous error exists */ myGlobalPtr->tempBuffer[myGlobalPtr->tempBufferPos] = ch; /* Put the char into the buffer */ myGlobalPtr->tempBufferPos++; /* Increment buffer position */ if (myGlobalPtr->tempBufferPos == kBufferSize) { /* If the buffer is full */ WriteTempBuffer(myGlobalPtr->filePos, kBufferSize, myGlobalPtr->tempBuffer, exportPBPtr, myGlobalPtr); myGlobalPtr->tempBufferPos = 0; /* Write the buffer to the output file */ } } /*----------------------------------------------------------------------*/ /* WriteTempBuffer This routine writes the specified number of bytes */ /* from the temporary buffer to the output file starting */ /* at the designated position in the file. */ /*----------------------------------------------------------------------*/ static void WriteTempBuffer(long position, long count, unsigned char *bufptr, register ExportParmBlkPtr exportPBPtr, register TMyGlobalPtr myGlobalPtr) { long bytes = count; /* Number of bytes to be written */ /* Set the file position for the data to be written */ if (*exportPBPtr->result = SetFPos(*exportPBPtr->refNum, fsFromStart, position)) return; /* Write the given number of bytes from the buffer to the file */ if (*exportPBPtr->result = FSWrite(*exportPBPtr->refNum, &bytes, bufptr)) return; myGlobalPtr->filePos += count; /* Increment filePos for the next call */ }